﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OS;

namespace OS.Instructions
{
    class LoadRegister : Instruction
    {
        public LoadRegister()
        {
        }//end default constructor

        /// <summary>
        /// Executes the the LR instruction
        /// </summary>
        public override void ExecuteLRInstruction()
        {
            Trace.WriteToTrace("Attempting to execute instruction: " + QueueManager.readyQueue.Peek().register_IR);
            int num;

            if (!int.TryParse(this.MemoryLocation, out num))
            {
                Trace.WriteToTrace("Invalid operand. Setting PI to 2.");
                CPU.PI = 2;
                return;
            }

            int virtualAddress = int.Parse(QueueManager.readyQueue.Peek().register_IR[2].ToString() + QueueManager.readyQueue.Peek().register_IR[3].ToString());
            int page = virtualAddress / 10;

            if(QueueManager.readyQueue.Peek().TLB.ContainsKey(page))
            {
                if(QueueManager.readyQueue.Peek().TLB[page] is Track)
                {
                    Track trk = (Track) QueueManager.readyQueue.Peek().TLB[page];

                    //swap
                    Trace.WriteToTrace("Need to swap track " + trk.TrackID + " into memory.");
                    Trace.WriteToTrace("Setting PI to 3 to request swap.");
                    CPU.PI = 3;
                }
                else if(QueueManager.readyQueue.Peek().TLB[page] is Frame)
                {
                    int physicalAddress = UserStorage.VirtualToPhysical(virtualAddress, QueueManager.readyQueue.Peek().register_PTR);

                    CPU.accumulator_R = "";

                    for(int i = 0; i < 4; i++)
                    {
                        CPU.accumulator_R += UserStorage.PhysicalMemory[physicalAddress, i];
                    }

                    Trace.WriteToTrace("Register R loaded with " + CPU.accumulator_R);
                }
            }
            else
            {
                QueueManager.readyQueue.Peek().terminationType = Termination.InvalidPageFault;
                return;
            }

            CPU.SI = 0;

        }//end ExecuteInstruction
    }//end LoadRegister
}//end OS.Instructions
